package com.ums.scumspay.service.impl;

import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ums.scumspay.constant.MerInfoConstant;
import com.ums.scumspay.constant.PayOrderNoConstant;
import com.ums.scumspay.constant.UrlConstant;
import com.ums.scumspay.entity.req.h5.H5PayBody;
import com.ums.scumspay.service.H5PayService;
import com.ums.scumspay.utils.CounterSignUtils;
import com.ums.scumspay.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class H5PayServiceImpl implements H5PayService {

    String appId= MerInfoConstant.h5AppId;

    String appKey=MerInfoConstant.h5AppKey;

    String mid=MerInfoConstant.mid;

    String tid=MerInfoConstant.tid;

    String urlNotify=MerInfoConstant.urlNotify;

    @Override
    public String sendPayRequest(String extOrderNo, String payAmount, String payWay){
        H5PayBody body = H5PayBody.builder()
                .requestTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
                .merOrderId(extOrderNo)
                .mid(mid)
                .tid(tid)
                .notifyUrl(urlNotify+"?extOrderNo="+extOrderNo+"-3")
                .instMid("H5DEFAULT")
                .totalAmount(payAmount).build();
        String sigForNetpay = null;
        try {
            sigForNetpay = CounterSignUtils.getOpenBodySigForNetpay(appId, appKey, JSONUtil.toJsonStr(body).toString());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        String url= UrlConstant.PAY_WAY.get(payWay)+sigForNetpay;
        String request = sendPay(url);
        log.info("支付请求响应{}"+request);
        Map<String,Integer> map = PayOrderNoConstant.getMap().get("h5");
        if (map==null){
            map=new HashMap<>();
        }
        map.put(extOrderNo,1);
        PayOrderNoConstant.getMap().put("h5",map);
        return request;
    }

    @Override
    public Map<String, String> sendQueryPayResult(String extOrderNo) {
        H5PayBody body = H5PayBody.builder()
                .requestTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
                .merOrderId(extOrderNo)
                .mid(mid)
                .tid(tid)
                .instMid("H5DEFAULT")
                .build();
        try {
            String authorization = CounterSignUtils.getOpenBodySig(appId, appKey, JSONUtil.toJsonStr(body).toString());
            String url="https://test-api-open.chinaums.com/v1/netpay/query";
            String request = sendQueryOrRefund(url, authorization, JSONUtil.toJsonStr(body).toString());
            log.info("支付请求响应{}"+request);
            try{
                return JSONUtil.toBean(request,Map.class);
            }catch (JSONException e){
                throw new RuntimeException();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        // new H5PayServiceImpl().sendQueryPayResult("84654826622321132");
        new H5PayServiceImpl().sendPayRequest(UUIDUtil.getUUID().substring(0,30),"1","zfb");
        // new H5PayServiceImpl().sendCancelRequest("1213123","1","234342342");
    }
    @Override
    public boolean sendCancelRequest(String extOrderNo, String refundAmount) {
        H5PayBody body = H5PayBody.builder()
                .requestTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
                .merOrderId(extOrderNo)
                .mid(mid)
                .tid(tid)
                .instMid("H5DEFAULT")
                .totalAmount(refundAmount)
                .build();
        try {
            String authorization = CounterSignUtils.getOpenBodySig(appId, appKey, JSONUtil.toJsonStr(body).toString());
            String url = "https://test-api-open.chinaums.com/v1/netpay/refund";
            String resp = sendQueryOrRefund(url, authorization, JSONUtil.toJsonStr(body).toString());
            log.info("退款查询{}"+resp);
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


    }


    /**
     * 发送httpGET请求
     * @param url 请求url
     * @return response
     */
    static String sendPay(String url){
        StringBuffer sbf = new StringBuffer();
        String response = "";
        PrintWriter out = null;
        BufferedReader in = null;
        try{
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            HttpURLConnection httpUrlConnection = (HttpURLConnection) conn;
            httpUrlConnection.setRequestMethod("GET");
            httpUrlConnection.setReadTimeout(15000);
            httpUrlConnection.setReadTimeout(60000);
            httpUrlConnection.connect();
            in = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream(),"UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                sbf.append(line);
                sbf.append("\r\n");
            }
            response = sbf.toString();
        }catch(Exception e){
            e.printStackTrace();
        } finally {
            try {
                if (out != null) { out.close();}
                if (in != null) {in.close();}
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return response;
    }

    /**
     * 发送http请求
     * @param url 请求url
     * @param authorization 认证报文
     * @param reqBody  请求体
     * @return response
     */
    static String sendQueryOrRefund(String url, String authorization, String reqBody){
        String response = "";
        PrintWriter out = null;
        BufferedReader in = null;
        try{
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            HttpURLConnection httpUrlConnection = (HttpURLConnection) conn;
            httpUrlConnection.setRequestProperty("Content-Type", "application/json");
            httpUrlConnection.setRequestProperty("authorization",authorization);
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setDoInput(true);
            out = new PrintWriter(httpUrlConnection.getOutputStream());
            out.write(reqBody);
            out.flush();
            httpUrlConnection.connect();
            in = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                response += line;
            }
        }catch(Exception e){
            e.printStackTrace();
        } finally {
            try {
                if (out != null) { out.close();}
                if (in != null) {in.close();}
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return response;
    }
}
